// ==UserScript==
// @name         Reddit GIF Downloader & Converter
// @namespace    http://tampermonkey.net/
// @version      0.2
// @description  下载 Reddit 上的 GIF 图片，支持转换为 GIF 格式
// @author       You
// @match        https://*.reddit.com/*
// @grant        GM_addStyle
// @grant        GM_xmlhttpRequest
// @grant        GM_download
// @connect      *
// ==/UserScript==

(function() {
    'use strict';

    // 添加样式
    const style = document.createElement('style');
    style.textContent = `
        .gif-download-container {
            position: absolute;
            top: 10px;
            right: 10px;
            z-index: 1000;
            display: flex;
            gap: 5px;
        }
        .gif-download-btn {
            background: #0079d3;
            color: white;
            border: none;
            padding: 5px 10px;
            border-radius: 4px;
            cursor: pointer;
        }
        .gif-download-btn:hover {
            background: #005999;
        }
        .converting {
            opacity: 0.7;
            cursor: wait;
        }
    `;
    document.head.appendChild(style);

    // 监听页面变化
    const observer = new MutationObserver((mutations) => {
        mutations.forEach((mutation) => {
            mutation.addedNodes.forEach((node) => {
                if (node.nodeType === 1) {
                    checkForGifs(node);
                }
            });
        });
    });

    observer.observe(document.body, {
        childList: true,
        subtree: true
    });

    // 检查 GIF
    function checkForGifs(node) {
        const videos = node.querySelectorAll('video');
        videos.forEach((video) => {
            if (!video.parentElement.querySelector('.gif-download-container')) {
                addDownloadButtons(video);
            }
        });
    }

    // 添加下载按钮
    function addDownloadButtons(video) {
        const container = video.parentElement;
        const buttonContainer = document.createElement('div');
        buttonContainer.className = 'gif-download-container';

        // MP4下载按钮
        const mp4Button = document.createElement('button');
        mp4Button.className = 'gif-download-btn';
        mp4Button.textContent = '下载 MP4';
        mp4Button.onclick = (e) => {
            e.preventDefault();
            e.stopPropagation();
            downloadMp4(video);
        };

        // GIF下载按钮
        const gifButton = document.createElement('button');
        gifButton.className = 'gif-download-btn';
        gifButton.textContent = '下载 GIF';
        gifButton.onclick = (e) => {
            e.preventDefault();
            e.stopPropagation();
            convertAndDownloadGif(video, gifButton);
        };

        buttonContainer.appendChild(mp4Button);
        buttonContainer.appendChild(gifButton);
        container.style.position = 'relative';
        container.appendChild(buttonContainer);
    }

    // 下载 MP4
    function downloadMp4(video) {
        const videoUrl = video.querySelector('source')?.src || video.src;
        if (!videoUrl) {
            alert('无法获取视频链接');
            return;
        }

        const timestamp = new Date().getTime();
        const filename = `reddit-video-${timestamp}.mp4`;

        GM_download({
            url: videoUrl,
            name: filename,
            onload: () => console.log('MP4下载完成'),
            onerror: (error) => console.error('下载失败:', error)
        });
    }

    // 转换并下载GIF
    async function convertAndDownloadGif(video, button) {
        try {
            // 设置转换中状态
            button.textContent = '转换中...';
            button.classList.add('converting');
            console.log("try to convert to gif")

            // 创建canvas
            const canvas = document.createElement('canvas');
            const ctx = canvas.getContext('2d');
            // 创建一个新的视频元素用于转换
            const tempVideo = document.createElement('video');
            tempVideo.crossOrigin = 'anonymous';
            // 获取视频blob数据
            const videoBlob = await fetchVideo(videoUrl);
            const blobUrl = URL.createObjectURL(videoBlob);
            // 加载视频
            await new Promise((resolve, reject) => {
                tempVideo.onloadedmetadata = resolve;
                tempVideo.onerror = reject;
                tempVideo.src = blobUrl;
            }); 
            canvas.width = video.videoWidth;
            canvas.height = video.videoHeight;

            // 创建GIF编码器
            const gif = new GIF({
                workers: 2,
                quality: 10,
                width: canvas.width,
                height: canvas.height
            });

            // 记录当前播放位置
            const currentTime = video.currentTime;
            video.currentTime = 0;

            // 等待视频加载
            await new Promise(resolve => {
                video.addEventListener('seeked', resolve, { once: true });
            });

            // 计算帧间隔 (假设30fps)
            const frameInterval = 1000 / 30;
            const duration = video.duration;
            const frameCount = Math.min(100, Math.floor(duration * 30)); // 限制最大帧数

            // 逐帧处理
            for (let i = 0; i < frameCount; i++) {
                video.currentTime = (i / frameCount) * duration;
                await new Promise(resolve => {
                    video.addEventListener('seeked', () => {
                        ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
                        gif.addFrame(ctx, { copy: true, delay: frameInterval });
                        resolve();
                    }, { once: true });
                });
            }

            // 恢复视频播放位置
            video.currentTime = currentTime;

            // 渲染GIF
            gif.on('finished', function(blob) {
                // 创建下载链接
                const url = URL.createObjectURL(blob);
                const timestamp = new Date().getTime();
                const filename = `reddit-gif-${timestamp}.gif`;

                // 下载文件
                GM_download({
                    url: url,
                    name: filename,
                    onload: () => {
                        console.log('GIF下载完成');
                        URL.revokeObjectURL(url);
                    },
                    onerror: (error) => console.error('下载失败:', error)
                });

                // 恢复按钮状态
                button.textContent = '下载 GIF';
                button.classList.remove('converting');
            });

            gif.render();

        } catch (error) {
            console.error('GIF转换失败:', error);
            button.textContent = '转换失败';
            button.classList.remove('converting');
            setTimeout(() => {
                button.textContent = '下载 GIF';
            }, 2000);
        }
    }

    // 使用GM_xmlhttpRequest获取视频数据
    function fetchVideo(url) {
        return new Promise((resolve, reject) => {
            GM_xmlhttpRequest({
                method: 'GET',
                url: url,
                responseType: 'blob',
                onload: function(response) {
                    resolve(response.response);
                },
                onerror: function(error) {
                    reject(error);
                }
            });
        });
    }

    // 初始检查
    checkForGifs(document.body);

    // 动态加载gif.js库
    const script = document.createElement('script');
    script.src = 'https://cdnjs.cloudflare.com/ajax/libs/gif.js/0.2.0/gif.js';
    document.head.appendChild(script);
})();